package com.superzlc.vjoy;

public class Main {
	static int devId = 1;
	static VJoy vjoy = VJoy.getInstance();
	public static void main(String[] args) throws Exception {
		test();
	}

	public static int test() throws Exception {

		// 获取设备属性 (Vendor ID, Product ID, Version Number)
		if (!vjoy.vJoyEnabled()) {
			print("vJoy不可用，请确保安装了vJoy并且没有禁用");
			vjoy.RelinquishVJD(devId);
			return -2;
		}

		print("制造商(vJoyManufacturer): %s", vjoy.GetvJoyManufacturerString());
		print("产品(vJoyProduct): %s", vjoy.GetvJoyProductString());
		print("版本(vJoyVersion): %d", vjoy.GetvJoyVersion());
		print("序列号(vJoySerialNumber): %s", vjoy.GetvJoySerialNumberString());
		print("是否支持力反馈(JoyFfbCap): %s", vjoy.vJoyFfbCap() ? "true" : "false");
		print("最大虚拟设备个数(vJoyMaxDevices): %s", vjoy.GetvJoyMaxDevices());
		print("存在虚拟设备个数(NumberExistingVJD): %s", vjoy.GetNumberExistingVJD());

		// 设备状态属性
		if (!vjoy.isVJDExists(devId)) {
			print("虚拟设备#%d不存在\n", devId);
			return -1;
		}
		int pid = vjoy.GetOwnerPid(devId);
		print("虚拟设备#%d的 OwnerPid: %d", devId, pid);

		int status = vjoy.GetVJDStatus(devId);
		switch (status) {
		case VJoy.VJD_STAT_OWN:
			print("虚拟设备#%d已经被占用", devId);
			break;
		case VJoy.VJD_STAT_FREE:
			print("虚拟设备#%d空闲，可以接收占用", devId);
			break;
		case VJoy.VJD_STAT_BUSY:
			print("虚拟设备#%d忙碌，已经被另一个终端占用", devId);
			return -3;
		case VJoy.VJD_STAT_MISS:
			print("虚拟设备#%d丢失，没有安装或已经被禁用", devId);
			return -4;
		default:
			print("虚拟设备#%d发生了错误", devId);
			return -1;
		};

		print("虚拟设备#%d按钮数(VJDButtonNumber): %d", devId, vjoy.GetVJDButtonNumber(devId));
		print("虚拟设备#%d离散苦力帽Number(VJDDiscPovNumber): %d", devId, vjoy.GetVJDDiscPovNumber(devId));
		print("虚拟设备#%d连续苦力帽Number(VJDContPovNumber): %d", devId, vjoy.GetVJDContPovNumber(devId));

		for (int axis : new int[]{
				VJoy.HID_USAGE_X,
				VJoy.HID_USAGE_Y,
				VJoy.HID_USAGE_Z,
				VJoy.HID_USAGE_RX,
				VJoy.HID_USAGE_RY,
				VJoy.HID_USAGE_RZ,
				VJoy.HID_USAGE_SL0,
				VJoy.HID_USAGE_SL1,
				VJoy.HID_USAGE_WHL,
				VJoy.HID_USAGE_POV,
				}) {
			boolean b = vjoy.GetVJDAxisExist(devId, axis);
			if (!b) {
				print("虚拟设备#%d不存在轴 %d", devId, axis);
				continue;
			}
			long max = vjoy.GetVJDAxisMax(devId, axis);
			long min = vjoy.GetVJDAxisMin(devId, axis);
			print("虚拟设备#%d轴%d值范围： %d : %d", devId, axis, min, max);
		}

		// 获取设备
		if (!vjoy.AcquireVJD(devId)) {
			print("获取虚拟设备#%d失败", devId);
			vjoy.RelinquishVJD(devId);
			return -1;
		} else {
			print("获取虚拟设备#%d成功", devId);
		}

		// 控制
		ctrl();

		// 释放
		print("释放虚拟设备#%d", devId);
		vjoy.RelinquishVJD(devId);
		return 0;
	}

	static void ctrl() throws Exception {
		vjoy.ResetAll();


		VJoy.JoyStickPosition data = new VJoy.JoyStickPosition();
		data.bDevice = (byte)devId;

		int i = 0;
		boolean b = true;
		while(true) {
			if (b)
				i++;
			else
				i--;
			int v = i * 2000;
			if (v > 32767 || v < 0) {
				b = !b;
				continue;
			}
			data.setX(v);
			if (!vjoy.UpdateVJD(devId, data)) {
				vjoy.AcquireVJD(devId);
			}

			Thread.sleep(10);
		}

	}


	static void ctrl4() throws Exception {
		vjoy.ResetAll();

		int x = 0;
		int y = 0;
		int min = 0;
		int max = 32767;
		int len = max - min;
		int step = (len) / 100;
		boolean by = true;

		int loop = 200;
		VJoy.JoyStickPosition data = new VJoy.JoyStickPosition();
		// Set destenition vJoy device
		data.bDevice = (byte)devId;

		while(loop-- > 0) {
			if (by)
				y += step;
			else
				y -= step;
			x = (int)(Math.sin(loop) * len / 2) + len / 2;


			for (int i = 0; i < 32; i++) {
				data.setButton(i, (i + 73) % (loop % 5 + 1) == 1);
			}

			int t = 32767 * loop / 150;

			data.setX(x);
			data.setY(y);
			data.setZ(t);
			data.setRX(t >> 1);
			data.setRY(t >> 2);
			data.setRZ(t >> 3);
			data.setSL0_wSlider(t >> 4);
			data.setSL1_wDial(t >> 5);

//			// Send position data to vJoy device
			if (!vjoy.UpdateVJD(devId, data)) {
				vjoy.AcquireVJD(devId);
			}

			Thread.sleep(100);



			if (y >= max) {
				by = false;
			} else if (y <= min) {
				by = true;
			}
		}

	}

	static void ctrl3() throws Exception {

		vjoy.ResetButtons(devId);
		vjoy.ResetPovs(devId);
		vjoy.ResetVJD(devId);
		vjoy.ResetAll();

		vjoy.SetContPov(10000, devId, (char)0);
		vjoy.SetDiscPov(10000, devId, (char)0);

		for (int i = 0; i < 32; i++) {
			vjoy.SetBtn(false, devId, (char)i);
		}

		int loop = 200;
		VJoy.JoyStickPosition data = new VJoy.JoyStickPosition();
		// Set destenition vJoy device
		data.bDevice = (byte)devId;

		while(loop-- > 0) {

			for (int i = 0; i < 32; i++) {
				data.setButton(i, (i + 73) % (loop % 5 + 1) == 1);
			}

			int t = 32767 * loop / 150;

			data.setX(t >> 2);
			data.setY(t >> 1);
			data.setZ(t);
			data.setRX(t >> 1);
			data.setRY(t >> 2);
			data.setRZ(t >> 3);
			data.setSL0_wSlider(t >> 4);
			data.setSL1_wDial(t >> 5);

//			// Send position data to vJoy device
			if (!vjoy.UpdateVJD(devId, data)) {
				vjoy.AcquireVJD(devId);
			}

			Thread.sleep(100);
		}
	}

	static void ctrl2() throws Exception {

		for (int i = 0; i < 32; i++) {
			vjoy.SetBtn(false, devId, (char)i);
		}

		int loop = 40;
		VJoy.JoyStickPosition data = new VJoy.JoyStickPosition();
		// Set destenition vJoy device
		data.bDevice = (byte)devId;

		short z = 0;
		long   Btns = 0;
		while(loop-- > 0) {
			// Set position data of axes
			if (z > 35000)
				z = 0;
			z += 200;
			data.wAxisZ = z;
			data.wAxisX = 32000 - z;
			data.wAxisY = z / 2 + 7000;

			// Set position data of buttons
			Btns = 1 << (z / 4000);
			data.lButtons = Btns;

//			// Send position data to vJoy device
			if (!vjoy.UpdateVJD(devId, data)) {
				vjoy.AcquireVJD(devId);
			}

////			// 独立设置轴
//			if (!vjoy.SetAxis(data.wAxisX, devId, VJoy.HID_USAGE_X))
//				print("set axis faild");
//			if (!vjoy.SetAxis(data.wAxisY, devId, VJoy.HID_USAGE_Y))
//				print("set axis faild");
//			if (!vjoy.SetAxis(data.wAxisZ, devId, VJoy.HID_USAGE_Z))
//				print("set axis faild");
//
////			// 独立设置按钮
			if (!vjoy.SetBtn(loop % 2 == 0, devId, (char)17))
				print("set btn faild");

			print("sleep and next loop");
			Thread.sleep(100);
		}
	}

	static void ctrl1() throws Exception {

		int loop = 20;
		VJoy.JoyStickPosition data = new VJoy.JoyStickPosition();
		// Set destenition vJoy device
		data.bDevice = (byte)devId;

		short z = 0;
		long   Btns = 0;
		while(loop-- > 0) {
			// Set position data of axes
			if (z > 35000)
				z = 0;
			z += 200;
			data.wAxisZ = z;
			data.wAxisX = 32000 - z;
			data.wAxisY = z / 2 + 7000;

			// Set position data of buttons
			Btns = 1 << (z / 4000);
			data.lButtons = Btns;

//			// Send position data to vJoy device
//			// 独立设置轴
			if (!vjoy.SetAxis(data.wAxisX, devId, VJoy.HID_USAGE_X))
				print("set axis faild");
			if (!vjoy.SetAxis(data.wAxisY, devId, VJoy.HID_USAGE_Y))
				print("set axis faild");
			if (!vjoy.SetAxis(data.wAxisZ, devId, VJoy.HID_USAGE_Z))
				print("set axis faild");

//			// 独立设置按钮
			if (!vjoy.SetBtn(isProbablyTrue(0.5), devId, (char)(loop % 32)))
				print("set btn faild");

			print("sleep and next loop");
			Thread.sleep(100);
		}
	}

    public static boolean isProbablyTrue(double probability) {
        return Math.random() > probability;
    }

	static void print(String format, Object ... args) {
		if (args.length == 0)
			System.out.println(format);
		else
			System.out.println(String.format(format, args));
	}
}
